package com.example.demo.util.crypto.sm3;

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

import java.io.UnsupportedEncodingException;
import java.security.Security;
import java.util.Arrays;


public class Sm3Utils {
    private static final String ENCODING = "UTF-8";

    static {
        Security.addProvider(new BouncyCastleProvider());
    }


    /**
     * 不提供秘钥的方式进行加密
     */
    public static String encrypt(String paramStr) {
        String resultHexString = "";
        try {
            byte[] srcDate    = paramStr.getBytes(ENCODING);
            byte[] resultHash = hash(srcDate);
            resultHexString = ByteUtils.toHexString(resultHash);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return resultHexString;
    }

    private static byte[] hash(byte[] srcDate) {
        SM3Digest digest = new SM3Digest();
        digest.update(srcDate, 0, srcDate.length);
        byte[] hash = new byte[digest.getDigestSize()];
        digest.doFinal(hash, 0);
        return hash;
    }

    /**
     * 提供秘钥的方式进行加密
     */
    private static byte[] hmac(byte[] key, byte[] srcData) {
        KeyParameter keyParameter = new KeyParameter(key);
        SM3Digest    digest       = new SM3Digest();
        HMac         mac          = new HMac(digest);
        mac.init(keyParameter);
        mac.update(srcData, 0, srcData.length);
        byte[] result = new byte[mac.getMacSize()];
        mac.doFinal(result, 0);
        return result;
    }

    /**
     * 加密数据的校验
     * 判断源数据与加密数据是否一致
     * 通过验证原数组和生成的hash数组是否为同一数组，验证2者是否为同一数据
     *
     * @param srcStr       原字符串
     * @param sm3HexString 16进制字符串
     */
    public static boolean verify(String srcStr, String sm3HexString) {
        boolean flag = false;
        try {
            byte[] srcData = srcStr.getBytes(ENCODING);
            byte[] sm3Hash = ByteUtils.fromHexString(sm3HexString);
            byte[] newHash = hash(srcData);
            flag = Arrays.equals(newHash, srcData);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return flag;
    }

    public static void main(String[] args) {
        Sm3Utils.encrypt("Hn888888");
        Sm3Utils.encrypt("Sc888888");

        Sm3Utils.encrypt(Sm3Utils.encrypt("Hn888888"));
        Sm3Utils.encrypt(Sm3Utils.encrypt("Sc888888"));
    }
}